import {
  Repository,
  FindManyOptions,
  FindOneOptions,
  DeepPartial,
} from 'typeorm';
import { BaseEntity } from './base.entity';

/**
 * 基础仓储
 * 提供通用的 CRUD、分页、软删除等操作
 * 对应 Java: BaseMapper
 */
export abstract class BaseRepository<T extends BaseEntity> {
  constructor(protected readonly repository: Repository<T>) {}

  /**
   * 创建实体
   */
  async create(entity: Partial<T>): Promise<T> {
    const newEntity = this.repository.create(entity as any);
    const result = await this.repository.save(newEntity);
    return Array.isArray(result) ? result[0] : result;
  }

  /**
   * 批量创建
   */
  async createMany(entities: Partial<T>[]): Promise<T[]> {
    const newEntities = this.repository.create(entities as any);
    return this.repository.save(newEntities);
  }

  /**
   * 根据ID查找
   */
  async findById(id: number): Promise<T | null> {
    return this.repository.findOne({ where: { id } } as FindOneOptions<T>);
  }

  /**
   * 查找单个实体
   */
  async findOne(options: FindOneOptions<T>): Promise<T | null> {
    return this.repository.findOne(options);
  }

  /**
   * 查找多个实体
   */
  async find(options?: FindManyOptions<T>): Promise<T[]> {
    return this.repository.find(options);
  }

  /**
   * 分页查询
   */
  async paginate(
    page: number,
    limit: number,
    options?: FindManyOptions<T>,
  ): Promise<{ data: T[]; total: number; page: number; limit: number }> {
    const [data, total] = await this.repository.findAndCount({
      ...options,
      skip: (page - 1) * limit,
      take: limit,
    });
    return {
      data,
      total,
      page,
      limit,
    };
  }

  /**
   * 更新实体
   */
  async update(id: number, entity: Partial<T>): Promise<T | null> {
    await this.repository.update(id, entity as any);
    return this.findById(id);
  }

  /**
   * 软删除
   */
  async softDelete(id: number): Promise<boolean> {
    const result = await this.repository.softDelete(id);
    return (result.affected || 0) > 0;
  }

  /**
   * 硬删除
   */
  async hardDelete(id: number): Promise<boolean> {
    const result = await this.repository.delete(id);
    return (result.affected || 0) > 0;
  }

  /**
   * 批量软删除
   */
  async softDeleteMany(ids: number[]): Promise<boolean> {
    const result = await this.repository.softDelete(ids);
    return (result.affected || 0) > 0;
  }

  /**
   * 统计数量
   */
  async count(options?: FindManyOptions<T>): Promise<number> {
    return this.repository.count(options);
  }
}
